home *** CD-ROM | disk | FTP | other *** search
/ PC Elektro 3 / PC-Elektro-3-cd1.bin / KBan 2.0 / KBANSRC.LZH / SRC / PROG / SAFEDRAW.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-01  |  7.2 KB  |  302 lines

  1. /*
  2.  * the class SAFE_DRAW
  3.  * Copyright (C) 1997 Kazutaka Hirata <khirata@jove.acs.unt.edu>
  4.  */
  5.  
  6. #include "stdafx.h"
  7.  
  8. #include "common/base.h"
  9.  
  10. #include "safedraw.h"
  11.  
  12. SAFE_DRAW::SAFE_DRAW(CDC* pDC)
  13.   : m_pDC(pDC)
  14. {
  15.   CRect rect;
  16.   pDC->GetClipBox(&rect);
  17.   m_xmin = rect.left;
  18.   m_xmax = rect.right;
  19.   m_ymin = rect.top;
  20.   m_ymax = rect.bottom;
  21.  
  22.   // Pen
  23.   m_pCurrentPen = new CPen(PS_SOLID, 1, RGB(0, 0, 0));
  24.   m_nPenStyle = PS_SOLID;
  25.   m_nWidth    = 1;
  26.   m_crColor   = RGB(0, 0, 0);
  27.   m_pOldPen = m_pDC->SelectObject(m_pCurrentPen);
  28.  
  29.   // Brush
  30.   m_pCurrentBrush = new CBrush(RGB(0, 0, 0));
  31.   m_brush_transparent = false;
  32.   m_brush_crColor     = RGB(0, 0, 0);
  33.   m_pOldBrush = m_pDC->SelectObject(m_pCurrentBrush);
  34.  
  35.   // XOR
  36.   m_OldXor = m_pDC->SetROP2(R2_XORPEN);
  37.   m_pDC->SetROP2(m_OldXor);
  38.   m_CurrentXor = m_OldXor;
  39. }
  40.  
  41. SAFE_DRAW::~SAFE_DRAW(void)
  42. {
  43.   m_pDC->SetROP2(m_OldXor);
  44.  
  45.   m_pDC->SelectObject(m_pOldBrush);
  46.   delete m_pCurrentBrush;
  47.  
  48.   m_pDC->SelectObject(m_pOldPen);
  49.   delete m_pCurrentPen;
  50. }
  51.  
  52. BOOL SAFE_DRAW::is_valid_x(int x) const
  53. {
  54.   return ((m_xmin <= x) && (x <= m_xmax)) ? TRUE : FALSE;
  55. }
  56.  
  57. BOOL SAFE_DRAW::is_valid_y(int y) const
  58. {
  59.   return ((m_ymin <= y) && (y <= m_ymax)) ? TRUE : FALSE;
  60. }
  61.  
  62. BOOL SAFE_DRAW::is_valid(int x, int y) const
  63. {
  64.   return (is_valid_x(x) && is_valid_y(y)) ? TRUE : FALSE;
  65. }
  66.  
  67. void SAFE_DRAW::set_pen(int nPenStyle, int nWidth, COLORREF crColor)
  68. {
  69.   if((m_nPenStyle != nPenStyle)
  70.   || (m_nWidth    != nWidth   )
  71.   || (m_crColor   != crColor  )) {
  72.     CPen* pNewPen = new CPen(nPenStyle, nWidth, crColor);
  73.     CPen* pOldPen = m_pDC->SelectObject(pNewPen);
  74.     delete pOldPen;
  75.     m_pCurrentPen = pNewPen;
  76.     m_nPenStyle = nPenStyle;
  77.     m_nWidth    = nWidth;
  78.     m_crColor   = crColor;
  79.   }
  80. }
  81.  
  82. void SAFE_DRAW::set_brush(int brush_transparent, COLORREF brush_crColor)
  83. {
  84.   if((m_brush_transparent != brush_transparent)
  85.   || (m_brush_crColor     != brush_crColor    )) {
  86.     CBrush* pNewBrush;
  87.     if(brush_transparent) {
  88.       pNewBrush = new CBrush;
  89.       LOGBRUSH lb;
  90.       lb.lbStyle = BS_NULL;
  91.       lb.lbColor = 0;
  92.       lb.lbHatch = 0;
  93.       pNewBrush->CreateBrushIndirect(&lb);
  94.     } else {
  95.       pNewBrush = new CBrush(brush_crColor);
  96.     }
  97.     CBrush* pOldBrush = m_pDC->SelectObject(pNewBrush);
  98.     delete pOldBrush;
  99.     m_pCurrentBrush = pNewBrush;
  100.     m_brush_transparent = brush_transparent;
  101.     m_brush_crColor     = brush_crColor;
  102.   }
  103. }
  104.  
  105. void SAFE_DRAW::set_rop(int Xor)
  106. {
  107.   if(m_CurrentXor != Xor) {
  108.     m_pDC->SetROP2(Xor);
  109.     m_CurrentXor = Xor;
  110.   }
  111. }
  112.  
  113. #define CLIP_X(x)                    \
  114.   if((x < m_xmin) && (m_xmax < x)) { \
  115.     return;                          \
  116.   }
  117.  
  118. #define CLIP_Y(y)                    \
  119.   if((y < m_ymin) && (m_ymax < y)) { \
  120.     return;                          \
  121.   }
  122.  
  123. #define CLIP_XY(x, y) \
  124.   CLIP_X(x);          \
  125.   CLIP_X(y);
  126.  
  127. #define CLIP_XX(x1, x2)            \
  128.   if(x2 < m_xmin || m_xmax < x1) { \
  129.     return;                        \
  130.   }
  131.  
  132. #define CLIP_YY(y1, y2)            \
  133.   if(y2 < m_ymin || m_ymax < y1) { \
  134.     return;                        \
  135.   }
  136.  
  137. void SAFE_DRAW::draw_point_core(int x, int y) const
  138. {
  139.   int xx = x + 1;
  140.   int yy = y + 1;
  141.   m_pDC->MoveTo(x , y );
  142.   m_pDC->LineTo(xx, yy);
  143. }
  144.  
  145. void SAFE_DRAW::draw_point(int x, int y, COLORREF color)
  146. {
  147.   int xx = x + 1;
  148.   int yy = y + 1;
  149.   CLIP_XY(x , y );
  150.   CLIP_XY(xx, yy);
  151.   set_pen(PS_SOLID, 1, color);
  152.   m_pDC->MoveTo(x , y );
  153.   m_pDC->LineTo(xx, yy);
  154. }
  155.  
  156. void SAFE_DRAW::draw_plain_circle(int x, int y, int r, COLORREF color, int fill, int xor)
  157. {
  158.   int x1 = x - r;
  159.   int x2 = x + r;
  160.   CLIP_XX(x1, x2);
  161.   int y1 = y - r;
  162.   int y2 = y + r;
  163.   CLIP_YY(y1, y2);
  164.   set_pen(PS_SOLID, 1, color);
  165.   set_rop(xor ? R2_XORPEN : R2_COPYPEN);
  166.   if(fill) {
  167.     set_brush(false, color);
  168.   } else {
  169.     set_brush(true, RGB(0, 0, 0));
  170.   }
  171.   m_pDC->Ellipse(x1, y1, x2, y2);
  172. }
  173.  
  174. void SAFE_DRAW::draw_plain_vertical_line(int x, int y1, int y2, int w, COLORREF color, int xor)
  175. {
  176.   CLIP_X(x);
  177.   sort2(y1, y2);
  178.   CLIP_YY(y1, y2);
  179.   y1 = max(y1, m_ymin);
  180.   y2 = min(y2, m_ymax);
  181.   set_pen(PS_SOLID, w, color);
  182.   set_rop(xor ? R2_XORPEN : R2_COPYPEN);
  183.   m_pDC->MoveTo(x, y1);
  184.   m_pDC->LineTo(x, y2);
  185. }
  186.  
  187. #if 0
  188. void SAFE_DRAW::draw_direct_vertical_line(int x, int y1, int y2, int w, COLORREF color, int xor)
  189. {
  190.   set_pen(PS_SOLID, w, color);
  191.   set_rop(xor ? R2_XORPEN : R2_COPYPEN);
  192.   m_pDC->MoveTo(x, y1);
  193.   m_pDC->LineTo(x, y2);
  194. }
  195. #endif
  196.  
  197. void SAFE_DRAW::draw_plain_holizontal_line(int x1, int x2, int y, int w, COLORREF color, int xor)
  198. {
  199.   CLIP_Y(y);
  200.   sort2(x1, x2);
  201.   CLIP_XX(x1, x2);
  202.   x1 = max(x1, m_xmin);
  203.   x2 = min(x2, m_xmax);
  204.   set_pen(PS_SOLID, w, color);
  205.   set_rop(xor ? R2_XORPEN : R2_COPYPEN);
  206.   m_pDC->MoveTo(x1, y);
  207.   m_pDC->LineTo(x2, y);
  208. }
  209.  
  210. void SAFE_DRAW::draw_plain_frame_box(int x1, int y1, int x2, int y2, COLORREF color, int xor)
  211. {
  212.   draw_plain_holizontal_line(x1, x2, y1, 1, color, xor);
  213.   draw_plain_holizontal_line(x1, x2, y2, 1, color, xor);
  214.   draw_plain_vertical_line  (x1, y1, y2, 1, color, xor);
  215.   draw_plain_vertical_line  (x2, y1, y2, 1, color, xor);
  216. }
  217.  
  218. void SAFE_DRAW::draw_plain_filled_box(int x1, int y1, int x2, int y2, COLORREF color, int xor)
  219. {
  220.   sort2(x1, x2);
  221.   CLIP_XX(x1, x2);
  222.   sort2(y1, y2);
  223.   CLIP_YY(y1, y2);
  224.  
  225.   x1 = max(x1, m_xmin);
  226.   x2 = min(x2, m_xmax);
  227.   y1 = max(y1, m_ymin);
  228.   y2 = min(y2, m_ymax);
  229.   set_pen(PS_SOLID, 1, color);
  230.   set_brush(false, color);
  231.   set_rop(xor ? R2_XORPEN : R2_COPYPEN);
  232.   m_pDC->Rectangle(x1, y1, x2, y2);
  233. }
  234.  
  235. void SAFE_DRAW::draw_plain_box(int x1, int y1, int x2, int y2, COLORREF color, int fill, int xor)
  236. {
  237.   if(fill) {
  238.     sort2(x1, x2);
  239.     sort2(y1, y2);
  240.     draw_plain_filled_box(x1, y1, x2 + 1, y2 + 1, color, xor);
  241.   } else {
  242.     draw_plain_frame_box(x1, y1, x2, y2, color, xor);
  243.   }
  244. }
  245.  
  246. void SAFE_DRAW::draw_plain_line(int x1, int y1, int x2, int y2, int w, COLORREF color, int xor)
  247. {
  248.   if(x1 == x2) {
  249.     draw_plain_vertical_line(x1, y1, y2, w, color, xor);
  250.   } else if(y1 == y2) {
  251.     draw_plain_holizontal_line(x1, x2, y1, w, color, xor);
  252.   } else {
  253. #if 0
  254.     if(x2 < x1) {
  255.       swap(x1, x2);
  256.       swap(y1, y2);
  257.     }
  258.     // The following is slightly different from CLIP_XX.
  259.     // Therefore, don't replace it!
  260.     if(x2 <= m_xmin || m_xmax <= x1) {
  261.       return;
  262.     }
  263.     CLIP_YY(min(y1, y2), max(y1, y2));
  264.     if(x1 < m_xmin) {
  265.       int r1 = m_xmin - x1;
  266.       int ra = x2 - x1;
  267.       x1 = m_xmin;
  268.       y1 = y1 + (y2 - y1) * r1 / ra;
  269.     }
  270.     if(m_xmax < x2) {
  271.       int r1 = m_xmax - x1;
  272.       int ra = x2 - x1;
  273.       x2 = m_xmax;
  274.       y2 = y1 + (y2 - y1) * r1 / ra;
  275.     }
  276.     if(y1 != y2) {
  277.       if(y2 < y1) {
  278.         swap(x1, x2);
  279.         swap(y1, y2);
  280.       }
  281.       if(y1 < m_ymin) {
  282.         int r1 = m_ymin - y1;
  283.         int ra = y2 - y1;
  284.         x1 = x1 + (x2 - x1) * r1 / ra;
  285.         y1 = m_ymin;
  286.       }
  287.       if(m_ymax < y2) {
  288.         int r1 = m_ymax - y1;
  289.         int ra = y2 - y1;
  290.         x2 = x1 + (x2 - x1) * r1 / ra;
  291.         y2 = m_ymax;
  292.       }
  293.     }
  294. #endif
  295.  
  296.     set_pen(PS_SOLID, w, color);
  297.     set_rop(xor ? R2_XORPEN : R2_COPYPEN);
  298.     m_pDC->MoveTo(x1, y1);
  299.     m_pDC->LineTo(x2, y2);
  300.   }
  301. }
  302.